package qfcfg

import (
	"encoding/xml"
	"io/ioutil"
	"os"

	qfcrypt "example.com/m/com.qfcrypt"
	qflog "example.com/m/com.qflog"
	"github.com/fsnotify/fsnotify"
)

// SConfig def
type SConfig struct {
	XMLName xml.Name `xml:"config"` // 指定最外层的标签为config
	Server  SServer  `xml:"server"` // 读取smtpServer配置项，并将结果保存到SmtpServer变量中
	Mysql   SMysql   `xml:"mysql"`
}

// SServer def
type SServer struct {
	IP     string `xml:"ip"`     // 读取ip
	WanIP  string `xml:"wan_ip"` // 读取wan_ip
	Enable int    `xml:"enable"` // 读取enable
	Port   int    `xml:"port"`   // 读取port
	Notice string `xml:"notice"` // 读取notice
	Auth   SAuth  `xml:"auth"`   // 读取auth
}

// SAuth def
type SAuth struct {
	Enable int    `xml:"enable"` // 读取enable
	Redis  SRedis `xml:"redis"`  // 读取redis
}

// PassWord def
type PassWord struct {
	Encrypt bool   `xml:"encrypt"` // 读取encrypt
	Value   string `xml:"value"`   // 读取value
}

// SRedis def
type SRedis struct {
	Host     string   `xml:"host"`     // 读取host
	Port     int      `xml:"port"`     // 读取port
	Password PassWord `xml:"password"` // 读取password
	Timeout  int      `xml:"timeout"`  // 读取timeout
}

// SMysql def
type SMysql struct {
	Host     string   `xml:"host"`     // 读取host
	Port     int      `xml:"port"`     // 读取port
	Username string   `xml:"username"` // 读取username
	Password PassWord `xml:"password"` // 读取password
	Dbname   string   `xml:"dbname"`   // 读取dbname
	Debug    bool     `xml:"debug"`    // 读取debug
}

// ServerConfig export var
var ServerConfig SConfig

// decryptPassWord def
func decryptPassWord(pwd *PassWord, note string) error {
	if pwd.Encrypt {
		decData, err := qfcrypt.ConfigAes.Decrypt(pwd.Value, "QFTECH")
		if err != nil {
			qflog.Sugare.Errorf("%s password decrypt err: %v", note, err)
			return err
		}

		decDataStr := string(decData[:])
		pwd.Value = decDataStr
		qflog.Sugare.Infof("%s password decrypt succeed, plain data: %s", note, decDataStr)
	}

	return nil
}

// readConfig def
func readConfig(path string) {
	file, err := os.Open(path) // For read access.
	if err != nil {
		qflog.Sugare.Errorf("error: %v", err)
		return
	}
	defer file.Close()
	data, err := ioutil.ReadAll(file)
	if err != nil {
		qflog.Sugare.Errorf("error: %v", err)
		return
	}

	ServerConfig = SConfig{}
	err = xml.Unmarshal(data, &ServerConfig)
	if err != nil {
		qflog.Sugare.Errorf("error: %v", err)
		return
	}

	sum := qflog.GetSum(1027, 4)
	qflog.TestVar = qflog.TestVar + 1
	qflog.Sugare.Infof("ip:%s port:%d sum:%v TestVar:%d", ServerConfig.Server.IP, ServerConfig.Server.Port, sum, qflog.TestVar)

	// 敏感信息解密
	_ = decryptPassWord(&ServerConfig.Server.Auth.Redis.Password, "redis")
	_ = decryptPassWord(&ServerConfig.Mysql.Password, "mysql")
}

// InitConfig def
func InitConfig() {
	readConfig("config.xml")

	// 监控文件
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		qflog.Sugare.Errorf("error:", err)
	}
	defer watcher.Close()

	// done := make(chan bool)
	go func() {
		for {
			select {
			case event, ok := <-watcher.Events:
				if !ok {
					return
				}
				qflog.Sugare.Infof("event:", event)
				if event.Op&fsnotify.Write == fsnotify.Write {
					qflog.Sugare.Infof("modified file:", event.Name)
					readConfig("config.xml")
				}
			case err, ok := <-watcher.Errors:
				if !ok {
					return
				}
				qflog.Sugare.Errorf("error:", err)
			}
		}
	}()

	err = watcher.Add("config.xml")
	if err != nil {
		qflog.Sugare.Errorf("error:", err)
	}
	// <-done
}
